<?php
/**
 * 志愿者报名API - 宣讲团报名功能
 * 用户可以申请成为博物馆志愿者/宣讲员
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit;
}

// 数据库配置
$dbConfig = [
    'host' => 'localhost',
    'name' => 'nzy_congqian_cn', 
    'user' => 'nzy_congqian_cn',
    'pass' => 'FsnXrDfDhm4wFJSX',
    'charset' => 'utf8mb4'
];

// 数据库连接
try {
    $dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['name']};charset={$dbConfig['charset']}";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    jsonResponse([
        'success' => false,
        'message' => '数据库连接失败: ' . $e->getMessage()
    ]);
}

// 响应函数
function jsonResponse($data) {
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function success($data = null, $message = '操作成功') {
    jsonResponse([
        'code' => 200,
        'success' => true,
        'message' => $message,
        'data' => $data,
        'timestamp' => time()
    ]);
}

function error($message = '操作失败', $code = 400) {
    jsonResponse([
        'code' => $code,
        'success' => false,
        'message' => $message,
        'data' => null,
        'timestamp' => time()
    ]);
}

// 保存常用观众信息
function saveCommonVisitorInfo($userId, $name, $phone, $idNumber = null, $idType = '身份证') {
    global $pdo;
    
    try {
        // 检查是否已存在相同的观众信息（通过姓名和手机号）
        $checkSql = "SELECT id FROM common_visitors 
                     WHERE user_id = ? AND name = ? AND phone = ?";
        $checkStmt = $pdo->prepare($checkSql);
        $checkStmt->execute([$userId, $name, $phone]);
        
        if (!$checkStmt->fetch()) {
            // 不存在则新增
            $insertSql = "INSERT INTO common_visitors 
                         (user_id, name, id_type, id_number, phone, created_at, updated_at)
                         VALUES (?, ?, ?, ?, ?, NOW(), NOW())";
            $insertStmt = $pdo->prepare($insertSql);
            $insertStmt->execute([$userId, $name, $idType, $idNumber, $phone]);
        } else {
            // 存在则更新最后修改时间
            $updateSql = "UPDATE common_visitors 
                         SET updated_at = NOW() 
                         WHERE user_id = ? AND name = ? AND phone = ?";
            $updateStmt = $pdo->prepare($updateSql);
            $updateStmt->execute([$userId, $name, $phone]);
        }
    } catch (Exception $e) {
        // 常用观众信息保存失败不影响主要功能
        error_log("Save common visitor failed: " . $e->getMessage());
    }
}

// 验证token（兼容版本）
function verifyToken($token) {
    global $pdo;
    
    if (empty($token)) {
        return false;
    }
    
    // 移除Bearer前缀
    if (strpos($token, 'Bearer ') === 0) {
        $token = substr($token, 7);
    }
    
    try {
        // 先检查表结构
        $hasTokenField = false;
        try {
            $columns = $pdo->query("SHOW COLUMNS FROM users LIKE 'token'")->fetchAll();
            $hasTokenField = (count($columns) > 0);
        } catch (Exception $e) {
            $hasTokenField = false;
        }
        
        if ($hasTokenField) {
            // 尝试新的token验证
            $sql = "SELECT * FROM users WHERE token = ?";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([$token]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($user) {
                // 检查用户状态和过期时间
                $isActive = ($user['status'] == 'active' || $user['status'] == 1);
                $isNotExpired = empty($user['token_expires']) || strtotime($user['token_expires']) > time();
                
                if ($isActive && $isNotExpired) {
                    return $user;
                }
                
                // 如果用户存在但token过期，更新过期时间并返回用户（兼容处理）
                if ($isActive) {
                    try {
                        $updateSql = "UPDATE users SET token_expires = DATE_ADD(NOW(), INTERVAL 7 DAY) WHERE id = ?";
                        $updateStmt = $pdo->prepare($updateSql);
                        $updateStmt->execute([$user['id']]);
                        return $user;
                    } catch (Exception $e) {
                        // 更新失败，继续下面的验证
                    }
                }
            }
        }
        
        // 备用方案1：尝试将token作为openid来验证
        $sql = "SELECT * FROM users WHERE openid = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$token]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($user) {
            $isActive = ($user['status'] == 'active' || $user['status'] == 1);
            if ($isActive) {
                return $user;
            }
        }
        
        // 备用方案2：尝试更宽松的状态检查
        $sql = "SELECT * FROM users WHERE (openid = ? OR (token IS NOT NULL AND token = ?)) AND status != 0";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$token, $token]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($user) {
            return $user;
        }
        
        return false;
        
    } catch (Exception $e) {
        // 最基础的验证
        try {
            $sql = "SELECT * FROM users WHERE openid = ? LIMIT 1";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([$token]);
            return $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Exception $e2) {
            return false;
        }
    }
}

// 获取认证token
function getAuthToken() {
    $headers = getallheaders();
    $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
    
    if (strpos($authHeader, 'Bearer ') === 0) {
        return substr($authHeader, 7);
    }
    
    return $_GET['token'] ?? $_POST['token'] ?? '';
}

// 获取当前用户
function getCurrentUser() {
    $token = getAuthToken();
    if (!$token) {
        error('需要登录', 401);
    }
    
    $user = verifyToken($token);
    if (!$user) {
        error('登录已过期，请重新登录', 401);
    }
    
    return $user;
}

// 提交志愿者申请
function submitVolunteerApplication() {
    global $pdo;
    
    $user = getCurrentUser();
    $input = json_decode(file_get_contents('php://input'), true);
    
    // 验证必填字段
    $required = ['name', 'gender', 'phone'];
    foreach ($required as $field) {
        if (empty($input[$field])) {
            error("缺少必填字段: $field");
        }
    }
    
    $name = trim($input['name']);
    $gender = $input['gender'];
    $phone = trim($input['phone']);
    $studentId = trim($input['student_id'] ?? '');
    $department = trim($input['department'] ?? '');
    $grade = trim($input['grade'] ?? '');
    $experience = trim($input['experience'] ?? '');
    $availableTime = trim($input['available_time'] ?? '');
    $selfIntroduction = trim($input['self_introduction'] ?? '');
    
    // 验证参数
    if (mb_strlen($name) > 50) {
        error('姓名长度不能超过50个字符');
    }
    
    if (!in_array($gender, ['male', 'female'])) {
        error('性别参数无效');
    }
    
    if (!preg_match('/^1[3-9]\d{9}$/', $phone)) {
        error('手机号格式不正确');
    }
    
    if (!empty($studentId) && mb_strlen($studentId) > 20) {
        error('学号长度不能超过20个字符');
    }
    
    if (!empty($department) && mb_strlen($department) > 100) {
        error('院系长度不能超过100个字符');
    }
    
    if (!empty($grade) && mb_strlen($grade) > 20) {
        error('年级长度不能超过20个字符');
    }
    
    if (!empty($experience) && mb_strlen($experience) > 1000) {
        error('相关经验描述不能超过1000个字符');
    }
    
    if (!empty($availableTime) && mb_strlen($availableTime) > 500) {
        error('可服务时间描述不能超过500个字符');
    }
    
    if (!empty($selfIntroduction) && mb_strlen($selfIntroduction) > 1000) {
        error('自我介绍不能超过1000个字符');
    }
    
    try {
        $pdo->beginTransaction();
        
        // 检查该用户是否已有有效的志愿者申请
        $existingSql = "SELECT id, status FROM volunteer_applications 
                       WHERE user_id = ? AND status IN (0, 1)";
        $existingStmt = $pdo->prepare($existingSql);
        $existingStmt->execute([$user['id']]);
        $existing = $existingStmt->fetch(PDO::FETCH_ASSOC);
        
        if ($existing) {
            $statusText = $existing['status'] == 0 ? '待审核' : '已通过';
            throw new Exception("您已有{$statusText}的志愿者申请，无需重复申请");
        }
        
        // 检查是否有相同手机号的申请
        $phoneSql = "SELECT id, name FROM volunteer_applications 
                    WHERE phone = ? AND status IN (0, 1)";
        $phoneStmt = $pdo->prepare($phoneSql);
        $phoneStmt->execute([$phone]);
        $phoneCheck = $phoneStmt->fetch(PDO::FETCH_ASSOC);
        
        if ($phoneCheck) {
            throw new Exception("该手机号已被申请人 {$phoneCheck['name']} 使用");
        }
        
        // 创建志愿者申请记录
        $insertSql = "INSERT INTO volunteer_applications 
                     (user_id, name, gender, phone, student_id, department, grade, 
                      experience, available_time, self_introduction, status, created_at, updated_at)
                     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NOW(), NOW())";
        
        $insertStmt = $pdo->prepare($insertSql);
        $insertStmt->execute([
            $user['id'],
            $name,
            $gender,
            $phone,
            $studentId,
            $department,
            $grade,
            $experience,
            $availableTime,
            $selfIntroduction
        ]);
        
        $applicationId = $pdo->lastInsertId();
        
        // 自动生成常用观众信息记录
        saveCommonVisitorInfo($user['id'], $name, $phone);
        
        $pdo->commit();
        
        success([
            'application_id' => $applicationId,
            'name' => $name,
            'gender' => $gender,
            'phone' => $phone,
            'status' => 'pending',
            'message' => '志愿者申请提交成功，我们会尽快审核您的申请'
        ], '志愿者申请提交成功');
        
    } catch (Exception $e) {
        $pdo->rollBack();
        error($e->getMessage());
    }
}

// 获取志愿者申请列表
function getVolunteerApplicationList() {
    global $pdo;
    
    $user = getCurrentUser();
    $page = max(1, intval($_GET['page'] ?? 1));
    $limit = min(50, max(1, intval($_GET['limit'] ?? 10)));
    $status = $_GET['status'] ?? '';
    $offset = ($page - 1) * $limit;
    
    try {
        // 构建查询条件
        $whereClause = "WHERE user_id = ?";
        $params = [$user['id']];
        
        if ($status !== '') {
            $whereClause .= " AND status = ?";
            $params[] = intval($status);
        }
        
        // 查询志愿者申请列表
        $sql = "SELECT * FROM volunteer_applications 
                $whereClause 
                ORDER BY created_at DESC 
                LIMIT $limit OFFSET $offset";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $applications = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // 获取总数
        $countSql = "SELECT COUNT(*) as total FROM volunteer_applications $whereClause";
        $countStmt = $pdo->prepare($countSql);
        $countStmt->execute($params);
        $total = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];
        
        // 处理数据格式
        $list = [];
        foreach ($applications as $application) {
            $statusMap = [0 => 'pending', 1 => 'approved', 2 => 'rejected'];
            
            $list[] = [
                'id' => intval($application['id']),
                'name' => $application['name'],
                'gender' => $application['gender'],
                'phone' => $application['phone'],
                'student_id' => $application['student_id'],
                'department' => $application['department'],
                'grade' => $application['grade'],
                'status' => $statusMap[$application['status']] ?? 'unknown',
                'review_note' => $application['review_note'],
                'created_at' => $application['created_at'],
                'updated_at' => $application['updated_at']
            ];
        }
        
        success([
            'list' => $list,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => intval($total),
                'pages' => ceil($total / $limit)
            ]
        ]);
        
    } catch (Exception $e) {
        error('获取志愿者申请列表失败: ' . $e->getMessage(), 500);
    }
}

// 获取志愿者申请详情
function getVolunteerApplicationDetail() {
    global $pdo;
    
    $user = getCurrentUser();
    $id = intval($_GET['id'] ?? 0);
    
    if (!$id) {
        error('申请ID不能为空');
    }
    
    try {
        $sql = "SELECT * FROM volunteer_applications WHERE id = ? AND user_id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id, $user['id']]);
        $application = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$application) {
            error('志愿者申请不存在', 404);
        }
        
        $statusMap = [0 => 'pending', 1 => 'approved', 2 => 'rejected'];
        
        success([
            'id' => intval($application['id']),
            'name' => $application['name'],
            'gender' => $application['gender'],
            'phone' => $application['phone'],
            'student_id' => $application['student_id'],
            'department' => $application['department'],
            'grade' => $application['grade'],
            'experience' => $application['experience'],
            'available_time' => $application['available_time'],
            'self_introduction' => $application['self_introduction'],
            'status' => $statusMap[$application['status']] ?? 'unknown',
            'review_note' => $application['review_note'],
            'created_at' => $application['created_at'],
            'updated_at' => $application['updated_at']
        ]);
        
    } catch (Exception $e) {
        error('获取志愿者申请详情失败: ' . $e->getMessage(), 500);
    }
}

// 更新志愿者申请信息
function updateVolunteerApplication() {
    global $pdo;
    
    $user = getCurrentUser();
    $id = intval($_GET['id'] ?? 0);
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$id) {
        error('申请ID不能为空');
    }
    
    try {
        // 检查申请是否存在且属于当前用户
        $sql = "SELECT * FROM volunteer_applications WHERE id = ? AND user_id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id, $user['id']]);
        $application = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$application) {
            error('志愿者申请不存在', 404);
        }
        
        // 只有待审核状态的申请可以修改
        if ($application['status'] != 0) {
            error('该申请已处理，无法修改');
        }
        
        // 构建更新数据
        $updateFields = [];
        $params = [];
        
        $allowedFields = [
            'name', 'gender', 'phone', 'student_id', 'department', 
            'grade', 'experience', 'available_time', 'self_introduction'
        ];
        
        foreach ($allowedFields as $field) {
            if (isset($input[$field])) {
                $value = trim($input[$field]);
                
                // 字段验证
                switch ($field) {
                    case 'name':
                        if (empty($value)) {
                            error('姓名不能为空');
                        }
                        if (mb_strlen($value) > 50) {
                            error('姓名长度不能超过50个字符');
                        }
                        break;
                    case 'gender':
                        if (!in_array($value, ['male', 'female'])) {
                            error('性别参数无效');
                        }
                        break;
                    case 'phone':
                        if (empty($value)) {
                            error('手机号不能为空');
                        }
                        if (!preg_match('/^1[3-9]\d{9}$/', $value)) {
                            error('手机号格式不正确');
                        }
                        break;
                    case 'student_id':
                        if (!empty($value) && mb_strlen($value) > 20) {
                            error('学号长度不能超过20个字符');
                        }
                        break;
                    case 'department':
                        if (!empty($value) && mb_strlen($value) > 100) {
                            error('院系长度不能超过100个字符');
                        }
                        break;
                    case 'grade':
                        if (!empty($value) && mb_strlen($value) > 20) {
                            error('年级长度不能超过20个字符');
                        }
                        break;
                    case 'experience':
                        if (!empty($value) && mb_strlen($value) > 1000) {
                            error('相关经验描述不能超过1000个字符');
                        }
                        break;
                    case 'available_time':
                        if (!empty($value) && mb_strlen($value) > 500) {
                            error('可服务时间描述不能超过500个字符');
                        }
                        break;
                    case 'self_introduction':
                        if (!empty($value) && mb_strlen($value) > 1000) {
                            error('自我介绍不能超过1000个字符');
                        }
                        break;
                }
                
                $updateFields[] = "$field = ?";
                $params[] = $value;
            }
        }
        
        if (empty($updateFields)) {
            error('没有需要更新的数据');
        }
        
        $updateFields[] = "updated_at = NOW()";
        $params[] = $id;
        
        $updateSql = "UPDATE volunteer_applications SET " . implode(', ', $updateFields) . " WHERE id = ?";
        $updateStmt = $pdo->prepare($updateSql);
        $updateStmt->execute($params);
        
        success(null, '志愿者申请信息更新成功');
        
    } catch (Exception $e) {
        error('更新志愿者申请信息失败: ' . $e->getMessage());
    }
}

// 撤销志愿者申请
function withdrawVolunteerApplication() {
    global $pdo;
    
    $user = getCurrentUser();
    $id = intval($_GET['id'] ?? 0);
    
    if (!$id) {
        error('申请ID不能为空');
    }
    
    try {
        // 检查申请是否存在且属于当前用户
        $sql = "SELECT * FROM volunteer_applications WHERE id = ? AND user_id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id, $user['id']]);
        $application = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$application) {
            error('志愿者申请不存在', 404);
        }
        
        // 只有待审核状态的申请可以撤销
        if ($application['status'] != 0) {
            error('该申请已处理，无法撤销');
        }
        
        // 删除申请记录
        $deleteSql = "DELETE FROM volunteer_applications WHERE id = ?";
        $deleteStmt = $pdo->prepare($deleteSql);
        $deleteStmt->execute([$id]);
        
        success(null, '志愿者申请已撤销');
        
    } catch (Exception $e) {
        error('撤销志愿者申请失败: ' . $e->getMessage());
    }
}

// 获取志愿者申请统计
function getVolunteerApplicationStats() {
    global $pdo;
    
    $user = getCurrentUser();
    
    try {
        $sql = "SELECT 
                    COUNT(*) as total_applications,
                    SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as pending_count,
                    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as approved_count,
                    SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as rejected_count,
                    DATE(MAX(created_at)) as latest_application_date
                FROM volunteer_applications 
                WHERE user_id = ?";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$user['id']]);
        $stats = $stmt->fetch(PDO::FETCH_ASSOC);
        
        success([
            'total_applications' => intval($stats['total_applications']),
            'pending_count' => intval($stats['pending_count']),
            'approved_count' => intval($stats['approved_count']),
            'rejected_count' => intval($stats['rejected_count']),
            'latest_application_date' => $stats['latest_application_date']
        ]);
        
    } catch (Exception $e) {
        error('获取统计信息失败: ' . $e->getMessage(), 500);
    }
}

// 处理请求
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';

try {
    switch ($method) {
        case 'GET':
            switch ($action) {
                case 'list':
                    getVolunteerApplicationList();
                    break;
                case 'detail':
                    getVolunteerApplicationDetail();
                    break;
                case 'stats':
                    getVolunteerApplicationStats();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        case 'POST':
            switch ($action) {
                case 'apply':
                    submitVolunteerApplication();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        case 'PUT':
            switch ($action) {
                case 'update':
                    updateVolunteerApplication();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        case 'DELETE':
            switch ($action) {
                case 'withdraw':
                    withdrawVolunteerApplication();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        default:
            error('不支持的请求方法');
    }
    
} catch (PDOException $e) {
    error('数据库错误: ' . $e->getMessage(), 500);
} catch (Exception $e) {
    error('服务器错误: ' . $e->getMessage(), 500);
}
?>